//*************************************************************************************
//* 作    者： z hunter
//* 创建时间： 2021-11-28 07:09:13
//*  描    述：

//* ************************************************************************************
using UnityEngine;
using UFrame.Audio;
using System.Collections.Generic;

public class AudioEmissionBehaviour : MonoBehaviour,UFrame.IAlive
{
    public AudioSpectrumCtrl m_spectrumCtrl;
    public float sensitivity = 2;
    [Tooltip("Adjusts height of the waveform")]
    public float amplitude = 2; // how sensitive is this script to the audio. This value is multiplied by the audio sample data.
    [Tooltip("Objects to move around in a circle.\n usually these are TrailRenderers")]
    public List<GameObject> objects; // the objects we want to move in a circle
    [Tooltip("How fast does the circle rotate?")]
    public float rotationSpeed = 10; // rotate objects around at this speed.
    [Tooltip("Radius of the circle")]
    public float radius = 10; // radius of the circle
    private List<float> startAngles; // starting angle of each object
    private float angle = 0; // current angle
    float rotSpeed; //temp container for rotation speed, used in the "Bump" method
    private Vector3[] startPositions;

    public bool Alive => this;

    void Awake()
    {
        //get the starting angle for each object
        startAngles = new List<float>();
        float anglePerObject = 360f / objects.Count;
        for (int i = 0; i < objects.Count; i++)
        {
            startAngles.Add(i * anglePerObject);
        }

        rotSpeed = rotationSpeed; // place rotation speed in a temp container
    }

    void Start()
    {
        startPositions = new Vector3[objects.Count];
        for (int i = 0; i < startPositions.Length; i++)
        {
            startPositions[i] = objects[i].transform.localPosition;
        }
        PositionObjects();
        TimerAgent.Instance.RegistLoopSafty(this, PositionObjects, 0.1f, UFrame.Timer.TimerUpdateType.LateUpdate);
    }

    //draw a circle around this object in scene view
    void OnDrawGizmos()
    {
        Gizmos.color = Color.white;
        Gizmos.DrawSphere(this.transform.position, 1);
    }

    //make everything rotate faster for a short period of time.
    //call from AudioEvent.OnBeat()
    public void Boost(float multiplier)
    {
        Invoke("ResetSpeed", .1f); //reset the speed in .1 seconds
        rotationSpeed = rotationSpeed * multiplier; // set the new rotation speed		
    }

    void ResetSpeed()
    {
        rotationSpeed = rotSpeed;
    }
    //position each object around this gameobject, based on rotation speed.
    bool PositionObjects()
    {
        int levelId = 0;
        var levels = AudioVisualManager.GetMeanLevels();
        //position the object accourding to the average
        angle += Time.smoothDeltaTime * rotationSpeed; // current rotation over time
        for (int i = 0; i < objects.Count; i++)
        {
            //angle of this object, = angle + startAngle
            float rad = (angle + startAngles[i]) * Mathf.Deg2Rad; // radians
            float newRad = radius; // new radius

            if (levelId >= levels.Length)
                levelId = 0;
            float value = levels[levelId];
            newRad = radius + value * amplitude;
            float x = Mathf.Cos(rad) * newRad; //update x and y pos
            float y = Mathf.Sin(rad) * newRad;
            //position each object around this one.
            objects[i].transform.localPosition = startPositions[i] + this.transform.right * x + this.transform.up * y;
        }
        return false;
    }
}
